package net.guruqu.rvoView;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashMap;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;

import com.gibbon.jme.context.JmeContext;
import com.jme.bounding.BoundingVolume;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import javax.swing.JCheckBox;
import javax.swing.JToggleButton;

public class SimulationViewComponent extends JPanel {
	JFrame fullScreenFrame;
	public JFrame normalFrame;
	ConfigFile configFile;

	class WholeViewCameraControl implements CameraControl {
		public Vector3f calculateCameraLocation() {
			float cameraDistance = getWholeDistance();
			float cameraLat = getWholeLat();
			float cameraAngle = getWholeAngle();
			float y = cameraDistance * FastMath.sin(cameraLat);
			float theta = cameraDistance * FastMath.cos(cameraLat);
			float x = FastMath.cos(cameraAngle) * theta;
			float z = FastMath.sin(cameraAngle) * theta;
			// System.out.println("X:" + x + " Y:" + y + " Z:" + z + " LAT:"
			// + cameraLat);
			return new Vector3f(x, y, z);
		}

		// float cameraAngle;
		// float cameraDistance;
		// float cameraLat;
		public void updateCamera(float t, Camera camera) {
			camera.setLocation(calculateCameraLocation());
			camera.lookAt(new Vector3f(), new Vector3f(0, 1, 0));
			camera.update();
		}

	}

	private float getChaseLat() {
		return latSlider.getValue() * FastMath.PI / 200f;
	}

	class ChaseCameraControl implements CameraControl {
		HashMap<Integer, SceneAgent> agentsToChase;
//		float smoothCamera;
		Vector3f smoothCamera;
		float smoothFactor = 0.9f;

		public HashMap<Integer, SceneAgent> getAgentsToChase() {
			return agentsToChase;
		}

		public void setAgentsToChase(HashMap<Integer, SceneAgent> agentsToChase) {
			this.agentsToChase = agentsToChase;
		}

		public int getChasingAgent() {
			ItemObject itemObject = (ItemObject) characterSelection
					.getSelectedItem();
			if (itemObject == null)
				return 0;
			return itemObject.agentId;
		}

		private SceneAgent getAgent() {
			return agentsToChase.get(getChasingAgent());
		}

		public Vector3f calculateLookAtLocation() {
			BoundingVolume bv = getAgent().getWorldBound();
			float height = 10000 - bv.distanceToEdge(new Vector3f(0, 10000, 0));
			Vector3f v3f = new Vector3f(getAgent().getLocalTranslation());
			v3f.y += height + 10;
			return v3f;
		}

		public Vector3f calculateCameraLocation() {
			float cameraDistance = getChaseDistance();
			// float cameraLat = FastMath.PI / 4f;
			float cameraLat = getChaseLat();
			float cameraAngle = 0;
			if (!lockView.isSelected()) {
				cameraAngle = getChaseAngle();
			} else {
				float angles[] = new float[3];
				getAgent().getLocalRotation().toAngles(angles);
				cameraAngle = FastMath.PI - angles[1];
			}
			BoundingVolume bv = getAgent().getWorldBound();
			float height = 10000 - bv.distanceToEdge(new Vector3f(0, 10000, 0));
			Vector3f v3f = new Vector3f(getAgent().getLocalTranslation());
			v3f.y += height + 10;
			// v3f.y += height;
			// setCameraCenter(v3f);

			float y = cameraDistance * FastMath.sin(cameraLat) + v3f.y;
			float theta = cameraDistance * FastMath.cos(cameraLat);
			float x = FastMath.cos(cameraAngle) * theta + v3f.x;
			float z = FastMath.sin(cameraAngle) * theta + v3f.z;
			// System.out.println("X:" + x + " Y:" + y + " Z:" + z + " LAT:"
			// + cameraLat);
			Vector3f nv = new Vector3f(x, y, z);
			if(smoothCamera==null)
				smoothCamera = new Vector3f(nv);
			Vector3f rv = nv.mult(1f-smoothFactor).add(smoothCamera.mult(smoothFactor));
			smoothCamera.set(rv);
			return rv;
		}

		// float cameraAngle;
		// float cameraDistance;
		// float cameraLat;
		public void updateCamera(float t, Camera camera) {
			camera.setLocation(calculateCameraLocation());
			camera.lookAt(calculateLookAtLocation(), new Vector3f(0, 1, 0));
			camera.update();
		}

	}

	private static final long serialVersionUID = 1L;

	/**
	 * This method initializes latSlider
	 * 
	 * @return javax.swing.JSlider
	 */
	private JSlider getLatSlider() {
		if (latSlider == null) {
			latSlider = new JSlider();
		}
		return latSlider;
	}

	/**
	 * This method initializes jPanel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			GridBagConstraints gridBagConstraints21 = new GridBagConstraints();
			gridBagConstraints21.gridx = 4;
			gridBagConstraints21.gridy = 0;
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints11.gridy = 0;
			gridBagConstraints11.weightx = 1.0;
			gridBagConstraints11.gridx = 0;
			jPanel = new JPanel();
			jPanel.setLayout(new GridBagLayout());
			jPanel.add(getLockView(), gridBagConstraints21);
			jPanel.add(getCharacterSelection(), gridBagConstraints11);
		}
		return jPanel;
	}

	/**
	 * This method initializes lockView
	 * 
	 * @return javax.swing.JCheckBox
	 */
	private JCheckBox getLockView() {
		if (lockView == null) {
			lockView = new JCheckBox();
			lockView.setText("Lock Character View");
			lockView.addItemListener(new java.awt.event.ItemListener() {
				public void itemStateChanged(java.awt.event.ItemEvent e) {
					if (lockView.isSelected())
						angleSlider.setEnabled(false);
					else
						angleSlider.setEnabled(true);
				}
			});
		}
		return lockView;
	}

	private static DisplayMode findBestFit(DisplayMode[] dms, int width,
			int height) {
		DisplayMode best = null;
		for (DisplayMode dm : dms) {
			System.out.println(dm.getWidth()+" "+dm.getHeight()+" "+dm.getBitDepth()+" "+dm.getRefreshRate());
			if (dm.getWidth() == width && dm.getHeight() == height) {
				if (best == null
						|| dm.getBitDepth() > best.getBitDepth()
						|| (dm.getBitDepth() == best.getBitDepth()
								&& dm.getRefreshRate() > best.getRefreshRate() && dm
								.getRefreshRate() < 120)) {
					best = dm;
				}
			}
		}
		return best;
	}

	/**
	 * This method initializes fullScreen
	 * 
	 * @return javax.swing.JToggleButton
	 */
	private JToggleButton getFullScreen() {
		if (fullScreen == null) {
			fullScreen = new JToggleButton();
			fullScreen.setText("Full Screen");
			fullScreen.addItemListener(new java.awt.event.ItemListener() {
				KeyAdapter adapter;

				public void itemStateChanged(java.awt.event.ItemEvent e) {
					if (fullScreen.isSelected()) {
						fullScreenFrame = new JFrame();
						fullScreenFrame.setUndecorated(true);
						viewPanel.remove(simulationView.canvasInstance);
						if (configFile.get("fsEclusive").equals("true")) {
							GraphicsDevice device = getGraphicsConfiguration()
									.getDevice();
							DisplayMode dms[] = device.getDisplayModes();
							int pw = new Integer(configFile
									.getProperty("width"));
							int ph = new Integer(configFile
									.getProperty("height"));
							DisplayMode best = findBestFit(dms, pw, ph);
							if (best == null)
								throw new RuntimeException(
										"Cannot find proper display mode");
							device.setFullScreenWindow(fullScreenFrame);
							device.setDisplayMode(best);
						} else {
							fullScreenFrame
									.setExtendedState(JFrame.MAXIMIZED_BOTH);
						}
					
						fullScreenFrame.setVisible(true);
						fullScreenFrame
								.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
						fullScreenFrame.add(simulationView.canvasInstance);
						adapter = new KeyAdapter() {
							public void keyPressed(KeyEvent e) {
								if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
									fullScreen.setSelected(false);
								}
							}
						};
						simulationView.canvasInstance.addKeyListener(adapter);
						simulationView.canvasInstance.requestFocus();
						simulationView.canvasInstance.repaint();
					} else {
						simulationView.canvasInstance
								.removeKeyListener(adapter);
						fullScreenFrame.remove(simulationView.canvasInstance);
						fullScreenFrame.setVisible(false);
						fullScreenFrame.dispose();
						viewPanel.add(simulationView.canvasInstance,
								BorderLayout.CENTER);
						viewPanel.updateUI();

						// SimulationViewComponent.this.repaint();
					}
				}
			});
		}
		return fullScreen;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	private JSlider angleSlider = null;
	private JTabbedPane cameraViewSelection = null;
	private JComboBox characterSelection = null;
	private JPanel chasingCamera = null;
	JmeContext context;
	private JPanel controlPanel = null;
	private JSlider distanceBar = null;

	private JSlider distanceSlider = null;

	RvoSetupInfo info;
	private JLabel jLabel = null;

	private JLabel jLabel1 = null;

	private JLabel jLabel2 = null;

	private JLabel jLabel3 = null;

	private JLabel jLabel4 = null;

	private JLabel jLabel5 = null;

	private JLabel jLabel51 = null;

	private JPanel jPanel1 = null;

	private JPanel jPanel2 = null;

	/**
	 * This method initializes jPanel
	 * 
	 * @return javax.swing.JPanel
	 */

	private JSlider latBar = null;

	private JButton loadButton = null;

	ModelRepository modelRepository;

	private JButton pauseButton = null;

	private JSlider rotateBar = null;

	SimulationView simulationView;

	private JLabel slabel = null;

	private JSlider speedSlider = null;

	private JPanel viewPanel = null;

	WholeViewCameraControl wholeViewCameraControl;
	ChaseCameraControl chaseCameraControl;
	private JSlider latSlider = null;
	private JLabel jLabel41 = null;
	private JPanel jPanel = null;
	private JCheckBox lockView = null;
	private JToggleButton fullScreen = null;

	/**
	 * This is the default constructor
	 */
	public SimulationViewComponent(ModelRepository modelRepository) {
		super();
		this.modelRepository = modelRepository;
		this.configFile = ConfigFile.get();
		initialize();
		HashMap<String, String> property = new HashMap<String, String>();
		property.put(SimulationView.MD_ROADMAP_FILE, ConfigFile.get()
				.getProperty("envDef"));

		wholeViewCameraControl = new WholeViewCameraControl();
		chaseCameraControl = new ChaseCameraControl();
		simulationView = new SimulationView(property, modelRepository);
		simulationView.setCameraControl(wholeViewCameraControl);

		new Thread() {
			@Override
			public void run() {
				try {
					context.waitFor();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				simulationView.setCanvas(context);
			}
		}.start();
	}

	/**
	 * This method initializes angleSlider
	 * 
	 * @return javax.swing.JSlider
	 */
	private JSlider getAngleSlider() {
		if (angleSlider == null) {
			angleSlider = new JSlider();
			angleSlider
					.addChangeListener(new javax.swing.event.ChangeListener() {
						public void stateChanged(javax.swing.event.ChangeEvent e) {
							// simulationView.setCameraAngle(rotateBar.getValue()
							// * FastMath.PI * 2f / 100f);
							simulationView.canvasInstance.repaint();
						}
					});
		}
		return angleSlider;
	}

	/**
	 * This method initializes cameraViewSelection
	 * 
	 * @return javax.swing.JTabbedPane
	 */
	private JTabbedPane getCameraViewSelection() {
		if (cameraViewSelection == null) {
			cameraViewSelection = new JTabbedPane();
			cameraViewSelection.setPreferredSize(new Dimension(645, 140));
			cameraViewSelection.addTab("Whole View", null, getJPanel1(), null);
			cameraViewSelection.addTab("Character View", null,
					getChasingCamera(), null);
			cameraViewSelection
					.addChangeListener(new javax.swing.event.ChangeListener() {
						public void stateChanged(javax.swing.event.ChangeEvent e) {
							if (cameraViewSelection.getSelectedIndex() == 0) {
								// simulationView
								// .setCameraMode(SimulationView.CM_WHOLEVIEW);
								simulationView
										.setCameraControl(wholeViewCameraControl);
							} else if (cameraViewSelection.getSelectedIndex() == 1) {
								// simulationView
								// .setCameraMode(SimulationView.CM_CHASE_CHR);
								// simulationView.setChaseAgent(0);
								chaseCameraControl
										.setAgentsToChase(simulationView
												.getSimulationAdapter()
												.getSceneAgents());
								simulationView
										.setCameraControl(chaseCameraControl);
								loadComboBox();
							}
						}
					});
		}
		return cameraViewSelection;
	}

	/**
	 * This method initializes characterSelection
	 * 
	 * @return javax.swing.JComboBox
	 */
	private JComboBox getCharacterSelection() {
		if (characterSelection == null) {
			characterSelection = new JComboBox();
			characterSelection
					.addItemListener(new java.awt.event.ItemListener() {
						public void itemStateChanged(java.awt.event.ItemEvent e) {
							simulationView.canvasInstance.repaint();
						}
					});
		}
		return characterSelection;
	}

	private void loadComboBox() {
		characterSelection.removeAllItems();
		HashMap<Integer, SceneAgent> agents = simulationView
				.getSimulationAdapter().getSceneAgents();
		for (int i : agents.keySet()) {
			ItemObject itemObject = new ItemObject();
			itemObject.agentId = i;
			characterSelection.addItem(itemObject);
		}
		characterSelection.updateUI();
	}

	private final static class ItemObject {
		public int agentId;

		public String toString() {
			return "Scene Agent #" + agentId;
		}
	}

	private float getChaseAngle() {
		return angleSlider.getValue() * FastMath.PI * 2f / 100f;
	}

	private void setChaseAngle(float s) {
		int vi = (int) (s * 100f / FastMath.PI / 2f);
		int v = ((vi % 100) + 100) % 100;
		angleSlider.setValue(v);
	}

	private float getChaseDistance() {
		float minD = 20;
		float maxD = 500;
		float inter = distanceSlider.getValue() / 100.0f;
		return minD * (1 - inter) + maxD * inter;
	}

	/**
	 * This method initializes chasingCamera
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getChasingCamera() {
		if (chasingCamera == null) {
			GridBagConstraints gridBagConstraints20 = new GridBagConstraints();
			gridBagConstraints20.gridx = 2;
			gridBagConstraints20.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints20.gridy = 3;
			GridBagConstraints gridBagConstraints19 = new GridBagConstraints();
			gridBagConstraints19.gridx = 1;
			gridBagConstraints19.gridy = 0;
			jLabel41 = new JLabel();
			jLabel41.setText("View Lat");
			GridBagConstraints gridBagConstraints18 = new GridBagConstraints();
			gridBagConstraints18.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints18.gridx = 2;
			gridBagConstraints18.gridy = 0;
			gridBagConstraints18.weightx = 1.0;
			GridBagConstraints gridBagConstraints17 = new GridBagConstraints();
			gridBagConstraints17.gridx = 1;
			gridBagConstraints17.gridy = 3;
			jLabel51 = new JLabel();
			jLabel51.setText("Character");
			GridBagConstraints gridBagConstraints16 = new GridBagConstraints();
			gridBagConstraints16.gridy = 2;
			gridBagConstraints16.gridx = 1;
			GridBagConstraints gridBagConstraints15 = new GridBagConstraints();
			gridBagConstraints15.gridy = 1;
			gridBagConstraints15.gridx = 1;
			jLabel5 = new JLabel();
			jLabel5.setText("View Angle");
			GridBagConstraints gridBagConstraints14 = new GridBagConstraints();
			gridBagConstraints14.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints14.gridy = 2;
			gridBagConstraints14.gridx = 2;
			gridBagConstraints14.weightx = 1.0;
			jLabel4 = new JLabel();
			jLabel4.setText("View Distance");
			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
			gridBagConstraints13.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints13.gridx = 2;
			gridBagConstraints13.gridy = 1;
			gridBagConstraints13.weightx = 1.0;
			chasingCamera = new JPanel();
			chasingCamera.setLayout(new GridBagLayout());
			chasingCamera.setPreferredSize(new Dimension(281, 101));
			chasingCamera.add(getDistanceSlider(), gridBagConstraints13);
			chasingCamera.add(jLabel4, gridBagConstraints15);
			chasingCamera.add(getAngleSlider(), gridBagConstraints14);
			chasingCamera.add(jLabel5, gridBagConstraints16);
			chasingCamera.add(jLabel51, gridBagConstraints17);
			chasingCamera.add(getLatSlider(), gridBagConstraints18);
			chasingCamera.add(jLabel41, gridBagConstraints19);
			chasingCamera.add(getJPanel(), gridBagConstraints20);
		}
		return chasingCamera;
	}

	/**
	 * This method initializes controlPanel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getControlPanel() {
		if (controlPanel == null) {
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.gridx = 1;
			gridBagConstraints6.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints6.gridy = 2;
			jLabel2 = new JLabel();
			jLabel2.setText("Angle");
			jLabel1 = new JLabel();
			jLabel1.setText("Latitude");
			jLabel = new JLabel();
			jLabel.setText("Distance");
			controlPanel = new JPanel();
			controlPanel.setLayout(new BorderLayout());
			controlPanel.setPreferredSize(new Dimension(640, 150));
			controlPanel.add(getJPanel2(), BorderLayout.SOUTH);
			controlPanel.add(getCameraViewSelection(), BorderLayout.CENTER);
		}
		return controlPanel;
	}

	/**
	 * This method initializes distanceBar
	 * 
	 * @return javax.swing.JSlider
	 */
	private JSlider getDistanceBar() {
		if (distanceBar == null) {
			distanceBar = new JSlider();
			distanceBar
					.addChangeListener(new javax.swing.event.ChangeListener() {
						public void stateChanged(javax.swing.event.ChangeEvent e) {
							// float minD = 100;
							// float maxD = 500;
							// float inter = distanceBar.getValue() / 100.0f;
							// simulationView.setCameraDistance(minD * (1 -
							// inter)
							// + maxD * inter);
							simulationView.canvasInstance.repaint();
						}
					});
		}
		return distanceBar;
	}

	/**
	 * This method initializes distanceSlider
	 * 
	 * @return javax.swing.JSlider
	 */
	private JSlider getDistanceSlider() {
		if (distanceSlider == null) {
			distanceSlider = new JSlider();
			distanceSlider
					.addChangeListener(new javax.swing.event.ChangeListener() {
						public void stateChanged(javax.swing.event.ChangeEvent e) {
							// float minD = 100;
							// float maxD = 500;
							// float inter = distanceBar.getValue() / 100.0f;
							// simulationView.setCameraDistance(minD * (1 -
							// inter)
							// + maxD * inter);
							simulationView.canvasInstance.repaint();
						}
					});
		}
		return distanceSlider;
	}

	/**
	 * This method initializes jPanel1
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanel1() {
		if (jPanel1 == null) {
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints.gridy = 2;
			gridBagConstraints.ipadx = 100;
			gridBagConstraints.weightx = 1.0;
			gridBagConstraints.gridx = 0;
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints1.gridy = 1;
			gridBagConstraints1.ipadx = 100;
			gridBagConstraints1.weightx = 1.0;
			gridBagConstraints1.gridx = 0;
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints2.gridy = 0;
			gridBagConstraints2.ipadx = 100;
			gridBagConstraints2.weightx = 1.0;
			gridBagConstraints2.gridx = 0;
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.gridx = 1;
			gridBagConstraints3.gridy = 2;
			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
			gridBagConstraints4.gridx = 1;
			gridBagConstraints4.gridy = 1;
			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
			gridBagConstraints5.gridx = 1;
			gridBagConstraints5.gridy = 0;
			jPanel1 = new JPanel();
			jPanel1.setLayout(new GridBagLayout());
			jPanel1.setPreferredSize(new Dimension(640, 54));
			jPanel1.add(jLabel2, gridBagConstraints5);
			jPanel1.add(jLabel, gridBagConstraints3);
			jPanel1.add(getRotateBar(), gridBagConstraints2);
			jPanel1.add(getLatBar(), gridBagConstraints1);
			jPanel1.add(getDistanceBar(), gridBagConstraints);
			jPanel1.add(jLabel1, gridBagConstraints4);
		}
		return jPanel1;
	}

	/**
	 * This method initializes jPanel2
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanel2() {
		if (jPanel2 == null) {
			GridBagConstraints gridBagConstraints22 = new GridBagConstraints();
			gridBagConstraints22.gridx = 5;
			gridBagConstraints22.gridy = 0;
			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
			gridBagConstraints12.gridx = 0;
			gridBagConstraints12.gridy = 0;
			jLabel3 = new JLabel();
			jLabel3.setText("Simulation Speed");
			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
			gridBagConstraints9.gridx = -1;
			gridBagConstraints9.gridy = -1;
			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
			gridBagConstraints7.gridx = 3;
			gridBagConstraints7.gridy = 0;
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.gridx = 0;
			gridBagConstraints10.gridy = 0;
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints8.gridx = 1;
			gridBagConstraints8.weightx = 1.0;
			jPanel2 = new JPanel();
			jPanel2.setLayout(new GridBagLayout());
			jPanel2.add(getSpeedSlider(), gridBagConstraints8);
			jPanel2.add(getLoadButton(), gridBagConstraints7);
			jPanel2.add(getPauseButton(), gridBagConstraints9);
			jPanel2.add(jLabel3, gridBagConstraints12);
			jPanel2.add(getFullScreen(), gridBagConstraints22);
		}
		return jPanel2;
	}

	/**
	 * This method initializes latBar
	 * 
	 * @return javax.swing.JSlider
	 */
	private JSlider getLatBar() {
		if (latBar == null) {
			latBar = new JSlider();
			latBar.addChangeListener(new javax.swing.event.ChangeListener() {
				public void stateChanged(javax.swing.event.ChangeEvent e) {
					// simulationView.setCameraLat(latBar.getValue() *
					// FastMath.PI
					// / 200f);
					simulationView.canvasInstance.repaint();
				}
			});
		}
		return latBar;
	}

	/**
	 * This method initializes loadButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getLoadButton() {
		if (loadButton == null) {
			loadButton = new JButton();
			loadButton.setText("Load");
			loadButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					simulationView.setSimulationPaused(true);
					simulationView.loadMapFile();
					pauseButton.setText("Resume");
					pauseButton.setEnabled(true);
					loadComboBox();
					simulationView.canvasInstance.repaint();

				}
			});
		}
		return loadButton;
	}

	/**
	 * This method initializes pauseButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getPauseButton() {
		if (pauseButton == null) {
			pauseButton = new JButton();
			pauseButton.setText("Pause");
			pauseButton.setEnabled(false);
			pauseButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if (pauseButton.getText().startsWith("P")) {
						simulationView.setSimulationPaused(true);
						pauseButton.setText("Resume");
					} else {
						simulationView.setSimulationPaused(false);
						pauseButton.setText("Pause");
					}
					simulationView.canvasInstance.repaint();
				}
			});
		}
		return pauseButton;
	}

	/**
	 * This method initializes rotateBar
	 * 
	 * @return javax.swing.JSlider
	 */
	private JSlider getRotateBar() {
		if (rotateBar == null) {
			rotateBar = new JSlider();
			rotateBar.setValue(13);
			rotateBar.addChangeListener(new javax.swing.event.ChangeListener() {
				public void stateChanged(javax.swing.event.ChangeEvent e) {
					// simulationView.setCameraAngle(rotateBar.getValue()
					// * FastMath.PI * 2f / 100f);
					simulationView.canvasInstance.repaint();
				}
			});
		}
		return rotateBar;
	}

	/**
	 * This method initializes speedSlider
	 * 
	 * @return javax.swing.JSlider
	 */
	private JSlider getSpeedSlider() {
		if (speedSlider == null) {
			speedSlider = new JSlider();
			speedSlider
					.addChangeListener(new javax.swing.event.ChangeListener() {
						public void stateChanged(javax.swing.event.ChangeEvent e) {
							float min = 0f;
							float max = 2f;
							float inter = speedSlider.getValue() / 100f;
							simulationView.setSimulationSpeed(min * (1 - inter)
									+ max * inter);
							simulationView.canvasInstance.repaint();
						}
					});
		}
		return speedSlider;
	}

	/**
	 * This method initializes viewPanel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getViewPanel() {
		if (viewPanel == null) {
			viewPanel = new JPanel();
			viewPanel.setLayout(new BorderLayout());

			context = ModelUtil.createCanvas(640, 480, modelRepository
					.getModelContext());
			Canvas canvas = context.getCanvas();
			viewPanel.add(canvas);
		}
		return viewPanel;
	}

	private float getWholeAngle() {
		return rotateBar.getValue() * FastMath.PI * 2f / 100f;
	}

	private float getWholeDistance() {
		float minD = 100;
		float maxD = 500;
		float inter = distanceBar.getValue() / 100.0f;
		return minD * (1 - inter) + maxD * inter;
	}

	private float getWholeLat() {
		return latBar.getValue() * FastMath.PI / 200f;
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(640, 800);
		this.setLayout(new BorderLayout());
		this.add(getViewPanel(), BorderLayout.CENTER);
		this.add(getControlPanel(), BorderLayout.SOUTH);
	}

	public JFrame getFullScreenFrame() {
		return fullScreenFrame;
	}

	public void setFullScreenFrame(JFrame fullScreenFrame) {
		this.fullScreenFrame = fullScreenFrame;
	}

}
